package com.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.exception.BusinessException;
import com.common.exception.code.BaseResponseCode;
import com.common.mq.FileMessage;
import com.common.mq.MQSender;
import com.common.utils.PageUtil;
import com.system.entity.File;
import com.system.mapper.FileMapper;
import com.system.service.FileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.vo.request.FilePageReqVO;
import com.system.vo.response.PageVO;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 文件信息存储表 服务实现类
 * </p>
 *
 * @author XueHeng
 * @since 2020-09-17
 */
@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {

    @Value("${file.path}")
    private String filePath;

    @Value("${file.base-url}")
    private String baseUrl;

    @Autowired
    private MQSender mqSender;

    @Override
    public PageVO<File> selectAll(FilePageReqVO vo) {
        Page<File> page = new Page<>(vo.getPageNum(),vo.getPageSize());
        IPage<File> files = this.baseMapper.selectAll(page, vo);
        return PageUtil.getPage(files);
    }

    @Override
    public void download(HttpServletResponse response, String fileId) {
        File file = this.baseMapper.selectById(fileId);
        ServletOutputStream outputStream = null;
        response.setContentType("multipart/form-data");
        try {
            //万能乱码问题解决
            String fileName = new String(file.getFileName().getBytes("UTF-8"), "ISO-8859-1");
            //设置文件下载响应头
            response.setHeader("Content-disposition", String.format("attachment;filename=%s",fileName));
            java.io.File file_ = FileUtils.getFile(filePath, file.getFileName());
            outputStream = response.getOutputStream();
            // 将目标文件输出到客户端
            IOUtils.write(FileUtils.readFileToByteArray(file_),outputStream);
        }catch (Exception e){
            throw new BusinessException(BaseResponseCode.OPERATION_ERROR);
        }finally {
            try {
                if(outputStream != null)
                    outputStream.close();
            } catch (IOException e) {
                throw new BusinessException(BaseResponseCode.OPERATION_ERROR);
            }
        }
    }

    @Override
    @Transactional
    public String upload(MultipartFile file, String userId,Integer type) {
        String fileUrl = null;
        if(file.isEmpty())
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        try {
            // 获取原文件名
            String originalFilename = file.getOriginalFilename();
            // 获取后缀名
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")+1).toLowerCase();
            // 上传文件
            String fileId = UUID.randomUUID().toString();
            String fileName = fileId+"."+suffix;
            fileUrl = baseUrl+fileName;
            java.io.File file_=new java.io.File(filePath+fileName);
            if(!file_.getParentFile().exists())
                file_.getParentFile().mkdirs();
            file.transferTo(file_);

            // 将文件信息保存到数据库中
            File files = new File();
            files.setId(fileId);
            files.setCreateId(userId);
            files.setCreateTime(new Date());
            files.setOriginalName(originalFilename);
            files.setExtensionName(suffix);
            files.setType(type);
            files.setFileName(fileName);
            files.setFileUrl(fileUrl);
            String size = FileUtils.byteCountToDisplaySize(file.getSize()).trim();
            files.setSize(size);
            FileMessage fileMessage = new FileMessage();
            fileMessage.setFile(files);
            this.mqSender.send(fileMessage);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(BaseResponseCode.UPLOAD_FILE_ERROR);
        }
        return fileUrl;
    }

    @Override
    @Transactional
    public void delete(List<String> fileUrl) {
        for(String url:fileUrl){
            // 删除文件数据库中的数据
            this.remove(new QueryWrapper<File>().eq("file_url",url));
            // 删除磁盘上的文件
            this.deleteFile(url);
        }
    }

    /*
    删除磁盘上的文件
     */
    private void deleteFile(String url){
        String fileName=url.substring(url.lastIndexOf("/")+1);
        java.io.File file=new java.io.File(filePath+fileName);
        if(file.exists()){
            file.delete();
        }
    }
}
